package leetcode.list_problem;

public class DoubleLinkedList {
    private int size ;
    private Node head;
    private Node tail;

    public boolean addFirst(int val){
        Node newNode = new Node(val);
        newNode.next = head;
        head.prev = newNode;
        head = newNode;
        size ++;
        return true;
    }

    public boolean addLast(int val){
        Node newNode = new Node(val);
        newNode.prev = tail;
        tail.next = newNode;
        tail = newNode;
        size ++;
        return true;
    }

    public boolean addIndex(int index , int val){
        if (index == 0){
            addFirst(val);
            return true;
        }else if(index == size){
            addLast(val);
            return true;
        }else {
            Node currentNode = node(index);
            Node newNode = new Node(currentNode.prev ,val , currentNode);
            newNode.prev.next = newNode;
            currentNode.prev = newNode;
            size ++;
            return true;
        }

    }

    public int get(int index){
        return node(index).val;
    }

    public boolean set(int index , int val){
        node(index).val = val;
        return true;
    }

    public boolean unLink(Node node){
        Node prev = node.prev;
        Node next = node.next;
        //看这个判断很灵性，刚好避开异常
        if (prev == null){
            head = node.next;
        }else {
            prev.next = next;//这里
            node.prev = null;
        }
        if (next == null){
            tail = node.prev;
        }else {
            next.prev = prev;
            node.next = null;
        }
        size --;
        return true;
    }

    public void removeIndex(int index){
        unLink(node(index));
        size --;
    }

    public void removeValueOnce(int val){
        for (Node node = head; node != null; node = node.next) {
            if (node.val == val){
                unLink(node);
                size --;
                break;
            }
        }
    }

    //这个全删就很有意思，因为每删一个长度会变，而且关系会变
    //引入一个节点过度即可
    public void removValueAll(int val){
        for (Node node = head; node != null;) {

            if (node.val == val){
                Node next = node.next;
                unLink(node);
                node = next;
            }else {
                node = node.next;
            }
        }
    }

    public Node node(int index){
        if (rangeCheck(index)){
            Node cow = head;
            for (int i = 0; i < index; i++) {
                cow = cow.next;
            }
            return cow;
        }else {
            return null;
        }
    }

    public boolean rangeCheck(int index){
        if (index < 0 || index > size) {
            System.out.println("The index error");
            return false;
        } else{
            return true;
        }
    }


}
class Node{
    Node prev;
    Node next;
    int val;
    public Node(int val){
        this.val = val;
    }
    public Node(Node prev , int val , Node next){
        this.prev = prev;
        this.val = val;
        this.next = next;
    }
}
